﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lacrima.Framework.Infrastructure
{
    public static class TypeUtils
    {
        /// <summary>
        /// 判断类型是否在类型列表中存在
        /// </summary>
        /// <param name="source">要匹配的类型</param>
        /// <param name="target">类型列表</param>
        /// <returns>类型列表中是否存在该类型，存在：true，不存在：false</returns>
        public static bool IsTypeIn(this Type source, params Type[] target)
        {
            if (source != null)
                return target.Any(o => o.Name.Equals(source.Name, StringComparison.OrdinalIgnoreCase));
            else
                return false;
        }

        /// <summary>
        /// 类型是否与类型列表中的类型相匹配，包括继承关系
        /// </summary>
        /// <param name="source">目标类型</param>
        /// <param name="target">类型列表</param>
        /// <returns>类型列表中的类型是否与该类型匹配，匹配：true，不匹配：false</returns>
        public static bool IsKindOf(this Type source, params Type[] target)
        {
            if (source != null)
                return target.Any(o => o.IsEquivalentTo(source) || source.IsAssignableFrom(o));
            else
                return false;
        }

        /// <summary>
        /// 对象的类型是否与目标类型相同
        /// </summary>
        /// <typeparam name="TSource">源对象类型</typeparam>
        /// <param name="source">源对象</param>
        /// <param name="target">目标类型</param>
        /// <returns>相同：true，不同：false</returns>
        public static bool TypeEquals<TSource>(this TSource source, Type target)
        {
            Type sourceType = source.GetType() ?? typeof(TSource);
            if (sourceType != null)
                return sourceType.Equals(target);
            else
                return false;
        }

        /// <summary>
        /// 对象的类型是否与目标类型等效
        /// </summary>
        /// <typeparam name="TSource">源对象类型</typeparam>
        /// <param name="source">源对象</param>
        /// <param name="target">目标类型</param>
        /// <returns>等效：true，不等效：false</returns>
        public static bool TypeEquivalentTo<TSource>(this TSource source, Type target)
        {
            Type sourceType = source.GetType() ?? typeof(TSource);
            if (sourceType != null)
                return sourceType.IsEquivalentTo(target);
            else
                return false;
        }
    }
}
